from wheels.pi.aio.Reactor import Reactor
from wheels.pi.aio.Select_ import Select


class SelectReactor(Reactor):

    def __init__(self):
        Reactor.__init__(self)
        self._read_queue = {}
        self._write_queue = {}


    def register(self, event, handler):
        # TODO: error if (event, handler) already defined
        if event == "r":
            self._read_queue[handler.handle().fileno()] = handler
        elif event == "w":
            self._write_queue[handler.handle().fileno()] = handler
        else:
            raise ValueError, "unknown event type"


    def unregister(self, event, handler):
        # TODO: error if (event, handler) undefined
        # Hint: catch KeyError
        if event == "r":
            del self._read_queue[handler.handle().fileno()]
        elif event == "w":
            del self._write_queue[handler.handle().fileno()]
        else:
            raise ValueError, "unknown event type"


    def run(self, blocking):
        if blocking:
            self._select(None)
        else:
            self._select(0)


    def _select(self, timeout):
        if not self._read_queue and not self._write_queue:
            return
        r, w, e = Select.select(self._read_queue,
                                self._write_queue,
                                [], timeout)
        for h in r.values():
            h.handle_event("r")
        for h in w.values():
            h.handle_event("w")
